
#include "stm32f10x.h"
#include "delay.h"

#define SRC_LED1_OFF GPIO_SetBits  (GPIOC,GPIO_Pin_13);
#define SRC_LED1_ON  GPIO_ResetBits(GPIOC,GPIO_Pin_13);

//-------------------控制线定义-----------------

#define  LCD_RS_PIN        GPIO_Pin_9            //数据命令选择 1:数据,0:命令
#define  LCD_RW_PIN        GPIO_Pin_8            //液晶读/写控制
#define  LCD_EN_PIN        GPIO_Pin_7            //液晶使能控制

#define  LCD_RST_PIN       GPIO_Pin_6            //液晶复位端口 低有效
#define  LCD_PSB_PIN       GPIO_Pin_5            //液晶并口/串口选择控制0：串行，1：并行8/4 位

#define Busy    0x80
#define DATA    GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7
#define CONTROL LCD_RS_PIN | LCD_RW_PIN | LCD_EN_PIN | LCD_RST_PIN | LCD_PSB_PIN;

#define  LCD_DATA_PORT      GPIOA   //液晶数据端口
#define  LCD_CONTROL_PORT   GPIOB   //液晶控制端口

#define  LCD_RS_L   GPIO_WriteBit(LCD_CONTROL_PORT, LCD_RS_PIN, Bit_RESET)
#define  LCD_RS_H   GPIO_WriteBit(LCD_CONTROL_PORT, LCD_RS_PIN, Bit_SET)
#define  LCD_RW_L   GPIO_WriteBit(LCD_CONTROL_PORT, LCD_RW_PIN, Bit_RESET)
#define  LCD_RW_H   GPIO_WriteBit(LCD_CONTROL_PORT, LCD_RW_PIN, Bit_SET)
#define  LCD_EN_L   GPIO_WriteBit(LCD_CONTROL_PORT, LCD_EN_PIN, Bit_RESET)
#define  LCD_EN_H   GPIO_WriteBit(LCD_CONTROL_PORT, LCD_EN_PIN, Bit_SET)

#define  LCD_PSB_L  GPIO_WriteBit(LCD_CONTROL_PORT, LCD_PSB_PIN, Bit_RESET)
#define  LCD_PSB_H  GPIO_WriteBit(LCD_CONTROL_PORT, LCD_PSB_PIN, Bit_SET)
#define  LCD_RST_L  GPIO_WriteBit(LCD_CONTROL_PORT, LCD_RST_PIN, Bit_RESET)
#define  LCD_RST_H  GPIO_WriteBit(LCD_CONTROL_PORT, LCD_RST_PIN, Bit_SET)

/**************************************************************
函数名称：LCD_Write_Command()
功    能：向液晶中写控制命令
参    数：CMD--控制命令
返回值  ：无
***************************************************************/
void LCD_Write_Command(uint8_t CMD)
{
    uint16_t  LCDTemp = 0x0000;
    Delay_Ms(100);

    //  Chk_Busy();
    //  Delay_Us(20);
    //  LCD_DataIo_Out();
    LCD_RS_L; Delay_Ms(5);
    LCD_RW_L; Delay_Ms(5);
    LCD_EN_L; Delay_Ms(5);
    //LCDTemp = LCDTemp | CMD ;
    GPIO_Write(LCD_DATA_PORT, CMD);
    Delay_Ms(5);
    LCD_EN_H; Delay_Ms(5);
    LCD_EN_L; Delay_Ms(5);
}

/**************************************************************
函数名称：LCD_Wite_Data()
功    能：向液晶中写入数据
参    数：Data--数据
返回值  ：无
***************************************************************/
void LCD_Write_Data(uint8_t Data)
{
    uint16_t  LCDTemp = 0x0000;
    Delay_Ms(100);
    //  Chk_Busy();
    //  Delay_us(20);
    //  LCD_DataIo_Out();
    LCD_RS_H; Delay_Ms(5);
    LCD_RW_L; Delay_Ms(5);
    LCD_EN_L; Delay_Ms(5);
    //LCDTemp = LCDTemp | Data ;
    GPIO_Write(LCD_DATA_PORT, Data);
    Delay_Ms(5);
    LCD_EN_H; Delay_Ms(5);
    LCD_EN_L; Delay_Ms(5);
}


/**************************************************************
函数名称：LCD_Init
功    能：初始化液晶模块
参    数：无
返回值  ：无
***************************************************************/
void LCD_Init(void)
{
    Delay_Ms(200);
    LCD_RST_L; // LCD复位
    Delay_Ms(200);
    LCD_RST_H;
    Delay_Ms(100);
    LCD_PSB_H;
    Delay_Ms(600);
    LCD_Write_Command(0x30);    //选择基本指令集
    Delay_Ms(200);
    LCD_Write_Command(0x30);    //选择基本指令集
    Delay_Ms(200);
    LCD_Write_Command(0x02);    //地址归位
    Delay_Ms(200);
    LCD_Write_Command(0x0C);    //开显示(无游标、不反白)
    Delay_Ms(200);
    LCD_Write_Command(0x01);    //清除显示，并且设定地址指针为00H
    Delay_Ms(5500);
    LCD_Write_Command(0x06);    //指定在资料的读取及写入时，设定游标的移动方向及指定显示的移位
    Delay_Ms(200);
    LCD_Write_Command(0x80);    //设定显示的起始地址
    Delay_Ms(200);
}

/**************************************************************
函数名称：PUT_Str
功    能：LCD显示一个字符
参    数：无
返回值  ：无
***************************************************************/
void PUT_Str(uint8_t X, uint8_t Y, uint8_t Data)
{
    if(Y < 1)   Y = 1;
    if(Y > 4)   Y = 4;        //y在1和4之间
    X = X & 0x0F;     //限制X不能大于16
    switch(Y)   //用Y选择第几行
    {
    case 1:
        X |= 0X80;
        break;//第一行
    case 2:
        X |= 0X90;
        break;//第二行
    case 3:
        X |= 0X88;
        break;//第三行
    case 4:
        X |= 0X98;
        break;//第四行
    }
    LCD_Write_Command(X);    // 写控制字 就是地址ddram地址
    LCD_Write_Data(Data);    // 写入数据

}
/**************************************************************
函数名称：PUT_String
功    能：LCD显示字符串
参    数：无
返回值  ：无
***************************************************************/
void PUT_String(uint8_t *S)
{
    while(*S > 0)
    {
        LCD_Write_Data(*S);
        S++;
        Delay_Ms(5);
    }
}

int main(void)
{
    u8 i;
    GPIO_InitTypeDef def;

    Delay_Init();
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    def.GPIO_Pin   = GPIO_Pin_13;
    def.GPIO_Mode  = GPIO_Mode_Out_PP;
    def.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &def);

    def.GPIO_Pin   = CONTROL;
    def.GPIO_Mode  = GPIO_Mode_Out_PP;
    def.GPIO_Speed = GPIO_Speed_50MHz ;
    GPIO_Init(GPIOB, &def);

    def.GPIO_Pin   = DATA;
    def.GPIO_Mode  = GPIO_Mode_Out_PP;
    def.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &def);

    for(i = 0; i < 5; i++)
    {
        SRC_LED1_ON;
        Delay_Ms(40);
        SRC_LED1_OFF;
        Delay_Ms(80);
    }

    LCD_Init();

    LCD_Write_Command(0x80);               // 行1位置控制
    Delay_Ms(10);
    PUT_String((uint8_t *)"0123456789");
    Delay_Ms(10);
    LCD_Write_Command(0x90);               //行2位置控制
    Delay_Ms(10);
    PUT_String((uint8_t *)"ABCDEFGHIJKLMN");
    Delay_Ms(10);
    LCD_Write_Command(0x88);                //行3位置控制
    Delay_Ms(10);
    PUT_String((uint8_t *)"www.xknife.net");
    Delay_Ms(10);
    LCD_Write_Command(0x98);                //行4位置控制
    Delay_Ms(10);
    PUT_String((uint8_t *)"==--[[{{@#$%}}]]--==");
    Delay_Ms(10);
    while (1)
    {
    }
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */
    while (1)
    {
    }
}
#endif
